#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jul 12 10:40:23 2022

@author: mac
"""

import os
import time
import json

dir_ui = "java/ui"
dir_viewmodel = "java/viewmodel"
dir_model = "java/model"
dir_navigation = "res/navigation"
dir_layout = "res/layout"
dir_domain = "java/domain"
dir_adapter = "java/ui/adapter"
dir_dialog = "java/ui/dialog"
dir_widget = "java/ui/widget"

def openfile(filename):
    result = ""
    with open(filename,'r',encoding="utf-8") as f:
        result = f.read()
    return result

def writefile(filename, content):
    with open(filename,'w',encoding="utf-8") as f:
        f.write(content)
        
def getdate():
    #获得当前时间时间戳
    now = int(time.time())
    #转换为其他日期格式,如:"%Y-%m-%d %H:%M:%S"
    timeStruct = time.localtime(now)
    strTime = time.strftime("%Y-%m-%d", timeStruct)
    return strTime

class Generator(object):
    
    def __init__(self, name,support_navigation=False,author="", model=""):
        self.name = name
        self.support_navigation = support_navigation
        self.author = author
        self.model = model
        self.generate()
        pass
    
    def load(self, path):
        return openfile("template/%s" % (path))
    
    def output(self, path, directory, content):
        cur_dir = "output/%s/%s" % (self.name, directory) 
        if not os.path.exists(cur_dir):
            os.makedirs(cur_dir)
     
        content = content.replace("[name]", self.hump_name()) \
                         .replace("[date]",getdate()) \
                         .replace("[model]",self.model) \
                         .replace("[underline_name]",self.name) \
                         .replace("[author]",self.author)
        fpath = cur_dir + "/" + path
        writefile(fpath, content)
        
    def generate(self):
        self.generateViewModel()
        self.generateRepository()
        self.generateService()
        self.generateBindAdapter()
        self.generateAdapterLayout()
        self.generateAdapter()
        self.generatePopmenu()
        self.generateCustomView()
        self.generateGradle()
        self.generateModel()
        
    def hump_name(self):
        ret=""
        names = self.name.split("_")
        for n in names:
            ret += n.title()
        return ret
        
    def generateViewModel(self):
        file_content = self.load("template_viewmodel.kt")
        activity_file_name = self.hump_name() + "ViewModel.kt"
        self.output(path=activity_file_name, directory=dir_viewmodel, content=file_content)

    def generateRepository(self):
        file_content = self.load("template_repository.kt")
        activity_file_name = self.hump_name() + "Repository.kt"
        self.output(path=activity_file_name, directory=dir_domain, content=file_content)

    def generateService(self):
        file_content = self.load("template_service.kt")
        activity_file_name = self.hump_name() + "Service.kt"
        self.output(path=activity_file_name, directory=dir_domain, content=file_content)
        
    def generateBindAdapter(self):
        file_content = self.load("template_bindadapter.kt")
        activity_file_name = "BindAdapter.kt"
        self.output(path=activity_file_name, directory=dir_adapter, content=file_content)
   
    def generateAdapterLayout(self):
        file_content = self.load("template_adapter_item.xml")
        activity_file_name = "adapter_" + self.name + "_item.xml"
        self.output(path=activity_file_name, directory=dir_layout, content=file_content)
    
    def generateAdapter(self):
        file_content = self.load("template_adapter.kt")
        activity_file_name = self.hump_name() + "Adapter.kt"
        self.output(path=activity_file_name, directory=dir_adapter, content=file_content)
    
    def generatePopmenu(self):
        file_content = self.load("template_popup.kt")
        activity_file_name = self.hump_name() + "Popup.kt"
        self.output(path=activity_file_name, directory=dir_dialog, content=file_content)
    
    def generateCustomView(self):
        file_content = self.load("template_custom_view.kt")
        activity_file_name = self.hump_name() + "CustomView.kt"
        self.output(path=activity_file_name, directory=dir_widget, content=file_content)
    
    def generateGradle(self):
        file_content = self.load("template_gradle.kts")
        activity_file_name = "build.gradle.kts"
        self.output(path=activity_file_name, directory="", content=file_content)
        
        
    def generateModel(self):
        file_content = self.load("template_model.kt")
        activity_file_name = self.model + ".kt"
        self.output(path=activity_file_name, directory=dir_model, content=file_content)


class ActivityGenerator(Generator):
    
    def generate(self):
        super().generate()
        self.generateActivity()
        if self.support_navigation == True:
            self.generateNavigation()
            self.generateNavigationLayout()
        else:
            self.generateActivityLayout()
        
        
    def generateActivity(self):
        if self.support_navigation == False:
            file_content = self.load("template_activity.kt")
            activity_file_name = self.hump_name() + "Activity.kt"
            self.output(path=activity_file_name, directory=dir_ui, content=file_content)
        else:
            file_content = self.load("template_activity_navigation.kt")
            activity_file_name = self.hump_name() + "Activity.kt"
            self.output(path=activity_file_name, directory=dir_ui, content=file_content)
            
    def generateNavigationLayout(self):
        file_content = self.load("template_activity_navigation_layout.xml")
        activity_file_name = "activity_%s.xml" % (self.name)
        self.output(path=activity_file_name, directory=dir_layout,content=file_content)
        
    def generateActivityLayout(self):
        file_content = self.load("template_activity_layout.xml")
        activity_file_name = "activity_%s.xml" % (self.name)
        self.output(path=activity_file_name, directory=dir_layout,content=file_content)
        
    def generateNavigation(self):
        file_content = self.load("template_navigation.xml")
        activity_file_name = "navigation_%s.xml" % (self.name)
        self.output(path=activity_file_name, directory=dir_navigation, content=file_content)
        

   
        
        
    
class FragmentGenerator(Generator):
    
    def generate(self):
        super().generate()
        self.generateFragment()
        self.generateFragmentLayout()
        
    def generateFragment(self):
        file_content = self.load("template_fragment.kt")
        activity_file_name = self.hump_name() + "Fragment.kt"
        self.output(path=activity_file_name, directory=dir_ui, content=file_content)

    def generateFragmentLayout(self):
        file_content = self.load("template_fragment_layout.xml")
        activity_file_name = "fragment_%s.xml" % (self.name)
        self.output(path=activity_file_name, directory=dir_layout, content=file_content)
        
        
        
class ApiGenerator(object):
    
    def __init__(self, api, params, comment,name):
        self.api = api
        self.params = params
        self.comment = comment
        self.name = name
        pass
    
    def load(self, path):
        return openfile("template/%s" % (path))
    
    def output(self, path, directory, content):
        cur_dir = "output/api/%s" % (directory) 
        if not os.path.exists(cur_dir):
            os.makedirs(cur_dir)
     
        content = content.replace("[rep_params]", self.rep_params()) \
                  .replace("[map_params]", self.map_params()) \
                  .replace("[vm_params]", self.vm_params()) \
                  .replace("[vm_call_params]", self.vm_call_params()) \
                  .replace("[method_name]", self.method_name()) \
                  .replace("[api_name]", self.api_name()) \
                  .replace("[api]", self.api) \
                  .replace("[api_comment]", self.comment) \
                  .replace("[name]", self.name)
        fpath = cur_dir + "/" + path
        writefile(fpath, content)
        
    
    def generate(self):
        self.generateRepository()
        self.generateViewModel()
        self.generateUrlConstant()
        self.generateService()
        pass
    
    def generateRepository(self):
        file_content = self.load("template_repository.kt")
        self.output(path="Repositroy.kt", directory=dir_domain, content=file_content)
    
    
    def generateViewModel(self):
        file_content = self.load("template_viewmodel.kt")
        self.output(path="ViewModel.kt", directory=dir_viewmodel, content=file_content)
    
    def generateUrlConstant(self):
        file_content = self.load("template_url_constant.kt")
        self.output(path="UrlConstant.kt", directory=dir_domain, content=file_content)

    def generateService(self):
        file_content = self.load("template_service.kt")
        self.output(path="Service.kt", directory=dir_domain, content=file_content)
        
    
    def rep_params(self):
        params = self.params.split(",")
        ret = ""
        for p in params:
            if p.endswith("[]"):
                ret += p.replace("[]","") + ":List<String>,"
            else:
                ret += p + ":String,"
        return ret

    def vm_call_params(self):
        params = self.params.split(",")
        ret = ""
        for p in params:
            if p.endswith("[]"):
                drop_p = p.replace("[]","")
                ret += "%s=%s," % (drop_p,drop_p)
            else:
                ret += "%s=%s," % (p,p)
        return ret

    def map_params(self):
        params = self.params.split(",")
        ret = ""
        for p in params:
            if p.endswith("[]"):
                drop_p = p.replace("[]","")
                ret +="\t\tval %s_obj = JsonArray()" % (drop_p) + "\r\n"
                ret += "\t\tfor (%s_item in %s) {" % (drop_p,drop_p) + "\r\n"
                ret += "\t\t\t%s_obj.add(%s_item)" % (drop_p,drop_p) + "\r\n"
                ret += "\t\t}" + "\r\n"
                ret += "\t\tparams[\"%s\"]=%s_obj" % (drop_p,drop_p) + "\r\n"
            else:    
                ret += "\t\tparams[\"%s\"]=%s" % (p,p) + "\r\n"
        return ret
    
    def vm_params(self):
        params = self.params.split(",")
        ret = ""
        for p in params:
            if p.endswith("[]"):
                ret += p.replace("[]","") + ":List<String>,"
            else:
                ret += p + ":String,"
        return ret

    def api_name(self):
        link = self.api.split("/")
        name = ""
        index = 0
        for n in link:
            if index < len(link)-1:
                name += n.upper() + "_"
            else:
                name += n.upper()
            index+=1
        return name

    def method_name(self):
        link = self.api.split("/")
        name = ""
        index = 0
        for n in link:
            if index > 0:
                name += n.title()
            else:
                name += n
            index+=1
        return name
    
    
class UICache(object):
    
    def __init__(self,name):
        self.name = name
    
    def load(self):
        path = "cache_"+self.name
        if not os.path.exists(path):
            self.write({})
            
        json_str = openfile("cache_"+self.name)
        return json.loads(json_str)
        
    def write(self, obj):
        writefile("cache_" + self.name, json.dumps(obj))
    
    
class observablefield(object):
    
    def __init__(self,setter=None, getter=None):
        self.setter = setter
        self.getter = getter
        
    def set(self,str):
        self.setter(str)
        
    def get(self):
        return self.getter()  
    

# ActivityGenerator(name="daolist", support_navigation=False, author="Johnson")

# FragmentGenerator(name="lobbylist", author="Johnson", model="LobbyItem")

# def phoneCallback(str):
#     print("callback %s" % str)

# phone = bindstr("wokao", phoneCallback)
# print(phone.get())
# phone.set("nidaye")

